<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title>GL</title>
</head>

<body onload="webGLStart()">
  <canvas id="webgl" width="500" height="500"></canvas>
  <script>

    let gl = null
    
    const v3PositionIndex = 0
    let triangleBuffer = null
    let program = null
    let indexBuffer = null
    // const inColor = 1
    let uniformColor = 0
    let uniformAnim = 0
    let animTime = 0

    window.requestAnimationFrame = (function () {
      return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function (callback, element) {
          window.setTimeout(callback, 1000 / 60)
        }
    })()
    
    function initgl () {
      /* 使用输入输出形式指定颜色
      // 顶点着色器源码
      const vertexShaderSource = `
                                  precision lowp float;
                                  attribute vec3 v3Position;
                                  attribute vec4 inColor;
                                  varying vec4 outColor;
                                  void main() {
                                    outColor = inColor;
                                    gl_Position =vec4(v3Position, 1.0);
                                  }
                                  `
      // 片元着色器源码
      const fragShaderSource = `
                                precision lowp float;
                                varying vec4 outColor;
                                void main() {
                                  gl_FragColor = outColor;
                                }
                                `
      */

      // uniform指定颜色
      // 顶点着色器源码
      const vertexShaderSource = `
                                  precision lowp float;
                                  attribute vec3 v3Position;
                                  uniform float anim;
                                  void main() {
                                    gl_Position =vec4(v3Position.x + anim, v3Position.y, v3Position.z, 1.0);
                                  }
                                  `
      // 片元着色器源码
      const fragShaderSource = `
                                precision lowp float;
                                uniform vec4 color;
                                void main() {
                                  gl_FragColor = color;
                                }
                                `

      const canvas = document.getElementById('webgl')
      gl = canvas.getContext('webgl')

      gl.viewport(0, 0, canvas.clientWidth, canvas.clientHeight)

      // 创建顶点着色器对象
      const vertexShader = gl.createShader(gl.VERTEX_SHADER)
      // 创建片元着色器对象
      const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)

      // 引入顶点、片元着色器源代码
      gl.shaderSource(vertexShader, vertexShaderSource)
      gl.shaderSource(fragmentShader, fragShaderSource)

      // 编译顶点、片元着色器
      gl.compileShader(vertexShader)
      gl.compileShader(fragmentShader)

      if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
        const err = gl.getShaderInfoLog(vertexShader)
        console.log('err: vertexShader,' + err)
        return
      }

      if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
        const err = gl.getShaderInfoLog(fragmentShader)
        console.log('err: fragmentShader,' + err)
        return
      }

      // 创建程序对象program
      program = gl.createProgram()

      // 附着顶点着色器和片元着色器到program
      gl.attachShader(program, vertexShader)
      gl.attachShader(program, fragmentShader)

      // 链接program
      gl.linkProgram(program)

      if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
        console.log('err: program')
        return
      }

      const jsArrayData = [
        -0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 1.0,
        0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 1.0,
        0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 1.0,
        -0.5, -0.5, 0.0, 1.0, 1.0, 0.0, 1.0
      ]

      const indexDatas = [
        0, 1, 2,
        0, 2, 3
      ]

      // gl.bindAttribLocation(program, inColor, 'inColor')
      uniformColor = gl.getUniformLocation(program, 'color')
      gl.uniform4f(uniformColor, 1, 0, 0, 1)
      uniformAnim = gl.getUniformLocation(program, 'anmi')
      gl.bindAttribLocation(program, v3PositionIndex, 'v3Position')

      // 顶点缓冲区
      triangleBuffer = gl.createBuffer()
      gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer)
      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(jsArrayData), gl.STATIC_DRAW)

      // 索引缓冲区
      indexBuffer = gl.createBuffer()
      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)
      gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexDatas), gl.STATIC_DRAW)
    }

    // 开始
    function webGLStart () {
      initgl()
      tick()
    }
    // 绘制
    function renderScene () {
      gl.clearColor(106.0 / 255.0, 121.0 / 255.0, 162.0 / 255.0, 1.0)
      gl.clear(gl.COLOR_BUFFER_BIT)

      gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer)
      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)

      animTime += 0.1

      // 使用program
      gl.useProgram(program)

      gl.uniform1f(uniformAnim, animTime)
      gl.enableVertexAttribArray(v3PositionIndex)
      // gl.enableVertexAttribArray(inColor)

      gl.vertexAttribPointer(v3PositionIndex, 3, gl.FLOAT, false, 4 * 7, 0)
      // gl.vertexAttribPointer(inColor, 4, gl.FLOAT, false, 4 * 7, 4 * 3)

      gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0)
      // gl.drawArrays(gl.TRIANGLES, 0, 3)

      // gl.useProgram(0)
    }

    function tick () {
      requestAnimationFrame(tick)
      renderScene()
    }
  </script>
</body>

</html>